package thunderbirdgtd.tests;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.LinkedList;

import org.junit.Test;

import thunderbirdgtd.GTDParent;
import thunderbirdgtd.entities.Action;
import thunderbirdgtd.entities.BaseActionOrProject;
import thunderbirdgtd.entities.Project;
import thunderbirdgtd.entities.Tag;


public class GTDParentTest {

	@Test
	public void testFindByTag() {
		GTDParent parent = new GTDParent();
		parent.projects = new LinkedList<Project>();
		
		
		// Create projects and add tags
		Project project1 = new Project("project1");
		try {
			project1.addTag(new Tag("tag1"));
			project1.addTag(new Tag("tag2"));
		} catch (Exception e) {
			e.printStackTrace();
			fail("Error adding tags to project.");
		}
		
		Project project2 = new Project("project2");
		try {
			project2.addTag(new Tag("tag3"));
		} catch (Exception e) {
			e.printStackTrace();
			fail("Error adding tags to project.");
		}
		
		Project project21 = new Project("project21");
		
		
		// Create actions and add tags
		Action action1 = new Action("action1");
		Action action2 = new Action("action2");
		Action action3 = new Action("action3");
		Action action4 = new Action("action4");
		try {
			action1.addTag(new Tag("tag1"));
			action2.addTag(new Tag("tag2"));
			action3.addTag(new Tag("tag3"));
			action4.addTag(new Tag("tag1"));
		} catch (Exception e) {
			e.printStackTrace();
			fail("Error adding tags to actions.");
		}
		
		
		// Associate actions to projects
		try {
			project1.addAction(action1);
			project1.addAction(action2);
			project2.addAction(action3);
			project21.addAction(action4);
		} catch (Exception e) {
			e.printStackTrace();
			fail("Error adding actions to projects.");
		}
		
		
		// Add projects to subprojects and base object
		project2.assignSubProject(project21);
		parent.projects.add(project1);
		parent.projects.add(project2);
		
		
		// For the test, order is important: it uses depth-first search.
		LinkedList<BaseActionOrProject> resultSet1 = new LinkedList<BaseActionOrProject>();
		resultSet1.add(project1);
		resultSet1.add(action1);
		resultSet1.add(action4);
		
		LinkedList<BaseActionOrProject> resultSet2 = new LinkedList<BaseActionOrProject>();
		resultSet2.add(project1);
		resultSet2.add(action2);
		
		LinkedList<BaseActionOrProject> resultSet3 = new LinkedList<BaseActionOrProject>();
		resultSet3.add(project2);
		resultSet3.add(action3);
		
		LinkedList<BaseActionOrProject> resultSet4 = new LinkedList<BaseActionOrProject>();
		
		
		assertTrue("Find by 'tag1'", resultSet1.equals( parent.findByTag("tag1")) );
		assertTrue("Find by 'tag2'", resultSet2.equals( parent.findByTag("tag2")) );
		assertTrue("Find by 'tag3'", resultSet3.equals( parent.findByTag("tag3")) );
		assertTrue("Find by 'tag4'", resultSet4.equals( parent.findByTag("tag4")) );
	}
}
